package com.zeus.base.smscenter.shiro;

import com.zeus.base.smscenter.utils.ConfigUtil;
import com.zeus.base.privilege.model.TbCompanyRoleMenuAuthority;
import com.zeus.base.privilege.model.TbUser;
import com.zeus.base.privilege.service.ICompanyRoleMenuAuthorityService;
import com.zeus.base.privilege.service.IUserService;
import com.zeus.base.privilege.utils.StringUtil;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.cas.CasAuthenticationException;
import org.apache.shiro.cas.CasRealm;
import org.apache.shiro.cas.CasToken;
import org.apache.shiro.session.InvalidSessionException;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.subject.SimplePrincipalCollection;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.util.CollectionUtils;
import org.jasig.cas.client.authentication.AttributePrincipal;
import org.jasig.cas.client.validation.Assertion;
import org.jasig.cas.client.validation.TicketValidator;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.*;

/**
 * Created by ShanFei on 2017-02-28.
 * 扩展CAS桥接器,订制角色体系和资源体系
 */
public class ShiroRealm extends CasRealm {
    @Autowired
    private IUserService iUserService;
    @Autowired
    private ICompanyRoleMenuAuthorityService iCompanyRoleMenuAuthorityService;
    @Autowired
    private ConfigUtil configUtil;
    /**
     * 权限认证
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        //获取登录时输入的用户名
        String userName=(String) principalCollection.fromRealm(getName()).iterator().next();
        //String currentUsername = (String)super.getAvailablePrincipal(principalCollection);
        //到数据库查是否有此对象
        TbUser user=iUserService.getUserByLoginName(userName);
        //if(user!=null && StringUtil.isNotEmpty(user.getCompanyIds()) && StringUtil.isNotEmpty(user.getRoleIds())){
        if(user!=null){
            HashMap<String,Object> params = new HashMap<String,Object>();
            params.put("companyRoleIds", StringUtil.startsWithAndEndsWith(user.getRoleIds()));
            params.put("companyIds", StringUtil.startsWithAndEndsWith(user.getCompanyIds()));
            params.put("productLineCode",configUtil.getProductLineCode());
            List<TbCompanyRoleMenuAuthority> roleMenuAuthorityList = iCompanyRoleMenuAuthorityService.findListRoleMenuAuthorityByParams(params);

            //权限信息对象info,用来存放查出的用户的所有的角色（role）及权限（permission）
            SimpleAuthorizationInfo authorizationInfo=new SimpleAuthorizationInfo();
            //用户的角色集合
            Set<String> rolesName = new HashSet<>();
            rolesName.add("admin");
            rolesName.add("administrator");
            authorizationInfo.setRoles(rolesName);
            //用户的角色对应的所有权限，如果只使用角色定义访问权限，下面的四行可以不要
            List<String> permission = new ArrayList<>();
            for (int i=0;i<roleMenuAuthorityList.size();i++){
                TbCompanyRoleMenuAuthority t = roleMenuAuthorityList.get(i);
                permission.add(t.getProductLineMenu().getMenuCode()+":"+t.getProductLineAuthority().getProductLineAuthorityCode());
            }
            authorizationInfo.addStringPermissions(permission);
            return authorizationInfo;
        }
        return null;
    }

    /**
     * 登录认证;
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(
            AuthenticationToken authenticationToken) throws AuthenticationException {
        CasToken casToken=(CasToken) authenticationToken;
        if(casToken == null)
            return null;
        String ticket = (String)casToken.getCredentials();
        if (ticket==null || ticket.equals(""))
            return null;
        TicketValidator ticketValidator = ensureTicketValidator();
        try {
            Assertion casAssertion = ticketValidator.validate(ticket, getCasService());
            AttributePrincipal casPrincipal = casAssertion.getPrincipal();
            String userName = casPrincipal.getName();
            Map attributes = casPrincipal.getAttributes();
            casToken.setUserId(userName);
            String rememberMeAttributeName = getRememberMeAttributeName();
            String rememberMeStringValue = (String) attributes.get(rememberMeAttributeName);
            //shiro是否记忆登陆用户
            boolean isRemembered = rememberMeStringValue != null && Boolean.parseBoolean(rememberMeStringValue);
            if (isRemembered)
                casToken.setRememberMe(true);
            List principals = CollectionUtils.asList(userName, attributes);
            PrincipalCollection principalCollection = new SimplePrincipalCollection(principals, getName());
            // 这里可以拿到Cas的登录账号信息,加载到对应权限体系信息放到缓存中...
            TbUser user=iUserService.getUserByLoginName(userName);
            //查出是否有此用户
            if(user!=null){
                SecurityUtils.getSubject().getSession().setAttribute("sessionUser", user);
            }
            //return new SimpleAuthenticationInfo(user,user.getPassword(),getName());
            return new SimpleAuthenticationInfo(principalCollection, ticket);
        //} catch (TicketValidationException e) {
        } catch (Exception e) {
            e.printStackTrace();
            throw new CasAuthenticationException((new StringBuilder()).append("Unable to validate ticket [")
                    .append(ticket).append("]").toString(), e);
        }
    }

    /**
     * 添加角色
     * @param username
     * @param info
     */
    /*
    private void addRole(String username, SimpleAuthorizationInfo info) {
        List<Role> roles = roleDao.findByUser(username);
        if(roles!=null&&roles.size()>0){
            for (Role role : roles) {
                info.addRole(role.getRoleName());
            }
        }
    }
    */
    /**
     * 添加权限
     * @param username
     * @param info
     * @return
     */
    /*
    private SimpleAuthorizationInfo addPermission(String username,SimpleAuthorizationInfo info) {
        List<Permission> permissions = permissionDao.findPermissionByName(username);
        for (Permission permission : permissions) {
            info.addStringPermission(permission.getUrl());//添加权限
        }
        return info;
    }
    */
    /**
     * 保存登录名
     */
    private void setSession(Object key, Object value){
        Session session = getSession();
        System.out.println("Session默认超时时间为[" + session.getTimeout() + "]毫秒");
        if(null != session){
            session.setAttribute(key, value);
        }
    }

    private Session getSession(){
        try{
            Subject subject = SecurityUtils.getSubject();
            Session session = subject.getSession(false);
            if (session == null){
                session = subject.getSession();
            }
            if (session != null){
                return session;
            }
        }catch (InvalidSessionException e){

        }
        return null;
    }
}
